package com.tanhua.management.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tanhua.common.mapper.AnalysisByDayMapper;
import com.tanhua.common.mapper.LogMapper;
import com.tanhua.common.mapper.UserInfoMapper;
import com.tanhua.common.mapper.UserMapper;
import com.tanhua.common.pojo.AnalysisByDay;
import com.tanhua.common.pojo.Log;
import com.tanhua.common.pojo.User;
import com.tanhua.common.pojo.UserInfo;
import com.tanhua.management.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
@Service
@Slf4j
public class DataDisplayService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private AnalysisByDayMapper analysisByDayMapper;
    @Autowired
    private LogMapper logMapper;
    @Autowired
    private UserInfoMapper userInfoMapper;

    /**
     * 查询概要统计信息
     * @return
     */
    public DataDispalyVo queryDataDispaly(){
        //查询累计用户
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        Integer cumulativeUsers = this.userMapper.selectCount(queryWrapper);
        DataDispalyVo dataDispalyVo = new DataDispalyVo();
        dataDispalyVo.setCumulativeUsers(cumulativeUsers);

        //30天活跃用户(去重)
        Integer activeByDay = getActiveByDay(30);
        dataDispalyVo.setActivePassMonth(activeByDay);

        //过去7天活跃用户(去重)
        Integer activeByDay1 = getActiveByDay(7);
        dataDispalyVo.setActivePassWeek(activeByDay1);

        //今日新增用户
        String[] agoByDay1 = getAgoByDay(1);
        String date = agoByDay1[1];
        QueryWrapper<AnalysisByDay> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("record_date",date)
                .select("num_registered");
        Integer register = this.analysisByDayMapper.selectCount(queryWrapper1);
        dataDispalyVo.setNewUserToday(register);

        //今日新增用户涨跌率
        String beforeDay = agoByDay1[0];
        QueryWrapper<AnalysisByDay>  queryWrapper2= new QueryWrapper<>();
        queryWrapper2.eq("record_date",beforeDay)
                .select("num_registered");
        Integer beforeRegister = this.analysisByDayMapper.selectCount(queryWrapper2);
        Integer newUsersToday = 0;
        if (0!=beforeRegister) {
            newUsersToday = (register / beforeRegister) - 1;
        }
        dataDispalyVo.setNewUsersTodayRate(newUsersToday);

        //今日登录次数
        QueryWrapper<AnalysisByDay>  queryWrapper3= new QueryWrapper<>();
        queryWrapper3.eq("record_date",date)
                .select("num_login");
        Integer loginTimeToday = this.analysisByDayMapper.selectCount(queryWrapper3);
        dataDispalyVo.setLoginTimesToday(loginTimeToday);

        //今日登录次数涨跌率
        QueryWrapper<AnalysisByDay>  queryWrapper4= new QueryWrapper<>();
        queryWrapper4.eq("record_date",beforeDay)
                .select("num_login");
        Integer beforeToday = this.analysisByDayMapper.selectCount(queryWrapper4);
        Integer loginTimesTodayRate = 0;
        if (0 !=beforeToday ){
            loginTimesTodayRate = (loginTimeToday/beforeToday)-1;
        }
        dataDispalyVo.setLoginTimesTodayRate(loginTimesTodayRate);

        //今日活跃用户
        QueryWrapper<AnalysisByDay>  queryWrapper5 = new QueryWrapper<>();
        queryWrapper5.eq("record_date",date)
                .select("num_active");
        Integer activeUserToday = this.analysisByDayMapper.selectCount(queryWrapper5);
        dataDispalyVo.setActiveUsersToday(activeUserToday);

        //今日活跃用户涨跌率
        QueryWrapper<AnalysisByDay>  queryWrapper6 = new QueryWrapper<>();
        queryWrapper6.eq("record_date",beforeDay)
                .select("num_active");
        Integer beforeActive = this.analysisByDayMapper.selectCount(queryWrapper6);
        Integer activeUsersTodayRate = 0;
        if (0 != beforeActive){
            activeUsersTodayRate = (activeUserToday/beforeActive)-1;
        }
        dataDispalyVo.setActiveUsersTodayRate(activeUsersTodayRate);

        //过去7天平均日使用时长
        dataDispalyVo.setUseTimePassWeek(2);
        //昨日活跃用户
        dataDispalyVo.setActiveUsersYesterday(beforeActive);

        //昨日活跃用户涨跌率
        String[] agoByDay = getAgoByDay(2);
        String beforeDay1 = agoByDay[0];
        QueryWrapper<AnalysisByDay>  queryWrapper7 = new QueryWrapper<>();
        queryWrapper7.eq("record_date",beforeDay1)
                .select("num_active");
        Integer beforeActive1 = this.analysisByDayMapper.selectCount(queryWrapper7);
        Integer activeUsersYesterdayRate = 0;
        if (0 != beforeActive1){
            activeUsersYesterdayRate = (beforeActive / beforeActive1) - 1;
        }
        dataDispalyVo.setActiveUsersYesterdayRate(activeUsersYesterdayRate);
        return dataDispalyVo;
    }

    //新增,活跃用户,次日留存率
    public PageResultUsers queryUsers(String sd,String ed,Integer type){
        PageResultUsers pageResultUsers = new PageResultUsers();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        if (type == 101){
                //今年
                List<ThisYearVo> list = new ArrayList();
                QueryWrapper<AnalysisByDay> queryWrapper = new QueryWrapper<>();
                queryWrapper.select("num_registered", "record_date")
                        .gt("record_date",sd)
                        .lt("record_date",ed);
            List<AnalysisByDay> analysisByDays = this.analysisByDayMapper.selectList(queryWrapper);

            for (AnalysisByDay analysisByDay : analysisByDays) {

                ThisYearVo thisYearVo = new ThisYearVo();
                String format = sdf.format(analysisByDay.getRecordDate());
                thisYearVo.setTitle(format);
                thisYearVo.setAmount(analysisByDay.getNumRegistered());
                list.add(thisYearVo);
            }
            pageResultUsers.setThisYear(list);

                //去年
            List<LastYearVo> list1 = new ArrayList();
                QueryWrapper<AnalysisByDay> queryWrapper1 = new QueryWrapper<>();
                //将今年的开始日期减一年
                Date parse = null;
                    try {
                        parse = sdf.parse(sd);
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                Calendar cal = Calendar.getInstance();
                cal.setTime(parse);
                cal.add(Calendar.YEAR,-1);
                Date addDate = cal.getTime();
                String startDayTime = sdf.format(addDate);
                //将今年的结束日期减一年
                Date parse1 = null;
                try {
                    parse1 = sdf.parse(sd);
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                Calendar cal1 = Calendar.getInstance();
                cal1.setTime(parse1);
                cal1.add(Calendar.YEAR,-1);
                Date addDate1 = cal1.getTime();
                String endDayTime = sdf.format(addDate1);
                queryWrapper1.select("num_registered", "record_date")
                        .gt("record_date",startDayTime)
                        .lt("record_date",endDayTime);
                List<AnalysisByDay> analysisByDays1 = this.analysisByDayMapper.selectList(queryWrapper1);
            for (AnalysisByDay analysisByDay : analysisByDays1) {
                LastYearVo lastYearVo = new LastYearVo();
                String format = sdf.format(analysisByDay.getRecordDate());
                lastYearVo.setTitle(format);
                lastYearVo.setAmount(analysisByDay.getNumRegistered());
                list1.add(lastYearVo);
            }
                pageResultUsers.setLastYear(list1);
        }else if (type == 102){
            //活跃用户
            //今年
            List<ThisYearVo> list1 = new ArrayList();
            QueryWrapper<AnalysisByDay> queryWrapper = new QueryWrapper<>();
            queryWrapper.select("num_active", "record_date")
                    .gt("record_date",sd)
                    .lt("record_date",ed);
            List<AnalysisByDay> analysisByDays = this.analysisByDayMapper.selectList(queryWrapper);
            for (AnalysisByDay analysisByDay : analysisByDays) {
                Date recordDate = analysisByDay.getRecordDate();
                ThisYearVo thisYearVo = new ThisYearVo();
                thisYearVo.setTitle(sdf.format(recordDate));
                thisYearVo.setAmount(analysisByDay.getNumActive());
                list1.add(thisYearVo);
            }
            pageResultUsers.setThisYear(list1);

            //去年
            QueryWrapper<AnalysisByDay> queryWrapper1 = new QueryWrapper<>();
            //将今年的开始日期减一年
            Date parse = null;
            try {
                parse = sdf.parse(sd);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            Calendar cal = Calendar.getInstance();
            cal.setTime(parse);
            cal.add(Calendar.YEAR,-1);
            Date addDate = cal.getTime();
            String startDayTime = sdf.format(addDate);
            //将今年的结束日期减一年
            Date parse1 = null;
            try {
                parse1 = sdf.parse(sd);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            Calendar cal1 = Calendar.getInstance();
            cal1.setTime(parse1);
            cal1.add(Calendar.YEAR,-1);
            Date addDate1 = cal1.getTime();
            String endDayTime = sdf.format(addDate1);
            queryWrapper1.select("num_active", "record_date")
                    .gt("record_date",startDayTime)
                    .lt("record_date",endDayTime);
            List<AnalysisByDay> analysisByDays1 = this.analysisByDayMapper.selectList(queryWrapper1);
            List<LastYearVo> list2 = new ArrayList<>();
            for (AnalysisByDay analysisByDay : analysisByDays1) {
                Date recordDate = analysisByDay.getRecordDate();
                String format = sdf.format(recordDate);
                LastYearVo lastYearVo = new LastYearVo();
                lastYearVo.setTitle(format);
                lastYearVo.setAmount(analysisByDay.getNumActive());
                list2.add(lastYearVo);
            }
            pageResultUsers.setLastYear(list2);
        }else if (type == 103){

            //次日留存率
            //今年
            List<ThisYearVo> list1 = new ArrayList();
            QueryWrapper<AnalysisByDay> queryWrapper = new QueryWrapper<>();
            queryWrapper.select("num_registered","num_retention1d","record_date")
                    .gt("record_date",sd)
                    .lt("record_date",ed);
            List<AnalysisByDay> analysisByDays = this.analysisByDayMapper.selectList(queryWrapper);
            for (AnalysisByDay analysisByDay : analysisByDays) {
                Date recordDate = analysisByDay.getRecordDate();
                ThisYearVo thisYearVo = new ThisYearVo();
                thisYearVo.setTitle(sdf.format(recordDate));
                Integer NumRetentionId = 0;
                Integer numRegistered = analysisByDay.getNumRegistered()==null ? 2:analysisByDay.getNumRegistered();
                Integer i = (numRegistered- 1);

                Integer numRetentionId = analysisByDay.getNumRetentionId() == null ? 2:analysisByDay.getNumRetentionId();
                if (0!= i) {
                    NumRetentionId = numRetentionId /i;
                }
                thisYearVo.setAmount(NumRetentionId);
                list1.add(thisYearVo);
            }
            pageResultUsers.setThisYear(list1);

            //去年
            QueryWrapper<AnalysisByDay> queryWrapper1 = new QueryWrapper<>();
            //将今年的开始日期减一年
            Date parse = null;
            try {
                parse = sdf.parse(sd);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            Calendar cal = Calendar.getInstance();
            cal.setTime(parse);
            cal.add(Calendar.YEAR,-1);
            Date addDate = cal.getTime();
            String startDayTime = sdf.format(addDate);
            //将今年的结束日期减一年
            Date parse1 = null;
            try {
                parse1 = sdf.parse(ed);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            Calendar cal1 = Calendar.getInstance();
            cal1.setTime(parse1);
            cal1.add(Calendar.YEAR,-1);
            Date addDate1 = cal1.getTime();
            String endDayTime = sdf.format(addDate1);
            queryWrapper1.select("num_active","num_retention1d", "record_date")
                    .gt("record_date",startDayTime)
                    .lt("record_date",endDayTime);
            List<AnalysisByDay> analysisByDays1 = this.analysisByDayMapper.selectList(queryWrapper1);
            List<LastYearVo> list2 = new ArrayList<>();
            for (AnalysisByDay analysisByDay : analysisByDays1) {
                Date recordDate = analysisByDay.getRecordDate();
                String format = sdf.format(recordDate);
                LastYearVo lastYearVo = new LastYearVo();
                lastYearVo.setTitle(format);
                Integer last = 0;
                Integer ac = Math.abs(analysisByDay.getNumActive()==null?2: analysisByDay.getNumActive());
                Integer ac1 = analysisByDay.getNumActive()-1;
                Integer ac2 = Math.abs(analysisByDay.getNumRetentionId()==null?2:analysisByDay.getNumRetentionId());
                if (ac2<0){
                    ac2=1;
                }
                if (0!=ac1) {
                    last = ac2 / ac;
                }
                lastYearVo.setAmount(last);
                list2.add(lastYearVo);
            }
        }
        return pageResultUsers;
    }

    //注册用户分布，行业top,年龄,性别,地区
    public PageResultbution queryDistribution(String sd,String ed){
        PageResultbution pageResultbution = new PageResultbution();
        //行业分布
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("industry")
                .groupBy("industry");
        List<UserInfo> userInfos = this.userInfoMapper.selectList(queryWrapper);
        List<IndustryDistributionVo> industry = new ArrayList<>();
        for (UserInfo userInfo : userInfos) {
            QueryWrapper<UserInfo> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.eq("industry",userInfo.getIndustry());
            Integer count = this.userInfoMapper.selectCount(queryWrapper1);
            IndustryDistributionVo industryDistributionVo = new IndustryDistributionVo();
            industryDistributionVo.setTitle(userInfo.getIndustry());
            industryDistributionVo.setAmount(count);
            industry.add(industryDistributionVo);
        }
            pageResultbution.setIndustryDistribution(industry);
        //年龄分布
        List<AgeDistributionVo> list = new LinkedList<>();
        AgeDistributionVo ageDistributionVo = new AgeDistributionVo();
        QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
        wrapper.select("age")
                .between("age",0,17);
        Integer count = this.userInfoMapper.selectCount(wrapper);
        ageDistributionVo.setTitle("0-17岁");
        ageDistributionVo.setAmount(count);
        list.add(ageDistributionVo);

        AgeDistributionVo ageDistributionVo1 = new AgeDistributionVo();
        QueryWrapper<UserInfo> wrapper1 = new QueryWrapper<>();
        wrapper1.select("age")
                .between("age",18,23);
        Integer count1 = this.userInfoMapper.selectCount(wrapper1);
        ageDistributionVo1.setTitle("18-23岁");
        ageDistributionVo1.setAmount(count1);
        list.add(ageDistributionVo1);

        AgeDistributionVo ageDistributionVo2 = new AgeDistributionVo();
        QueryWrapper<UserInfo> wrapper2 = new QueryWrapper<>();
        wrapper2.select("age")
                .between("age",24,30);
        Integer count2 = this.userInfoMapper.selectCount(wrapper2);
        ageDistributionVo2.setTitle("24-30岁");
        ageDistributionVo2.setAmount(count2);
        list.add(ageDistributionVo2);

        AgeDistributionVo ageDistributionVo3 = new AgeDistributionVo();
        QueryWrapper<UserInfo> wrapper3 = new QueryWrapper<>();
        wrapper3.select("age")
                .between("age",31,40);
        Integer count3 = this.userInfoMapper.selectCount(wrapper3);
        ageDistributionVo3.setTitle("31-40岁");
        ageDistributionVo3.setAmount(count3);
        list.add(ageDistributionVo3);

        AgeDistributionVo ageDistributionVo4 = new AgeDistributionVo();
        QueryWrapper<UserInfo> wrapper4 = new QueryWrapper<>();
        wrapper4.select("age")
                .between("age",41,50);
        Integer count4 = this.userInfoMapper.selectCount(wrapper4);
        ageDistributionVo4.setTitle("41-50岁");
        ageDistributionVo4.setAmount(count4);
        list.add(ageDistributionVo4);

        AgeDistributionVo ageDistributionVo5 = new AgeDistributionVo();
        QueryWrapper<UserInfo> wrapper5 = new QueryWrapper<>();
        wrapper5.select("age")
                .gt("age",50);
        Integer count5 = this.userInfoMapper.selectCount(wrapper5);
        ageDistributionVo5.setTitle("51-100岁");
        ageDistributionVo5.setAmount(count5);
        list.add(ageDistributionVo5);
        pageResultbution.setAgeDistribution(list);

        //性别分布男生
        List<GenderDistributionVo> list2 = new ArrayList();
        GenderDistributionVo genderDistributionVo = new GenderDistributionVo();
        QueryWrapper<UserInfo> wrapper6 = new QueryWrapper<>();
        wrapper6.select("sex")
                .eq("sex",1);
        Integer count6 = this.userInfoMapper.selectCount(wrapper6);
        genderDistributionVo.setTitle("男性用户");
        genderDistributionVo.setAmount(count6);
        list2.add(genderDistributionVo);

        //性别分布女生
        GenderDistributionVo genderDistributionVo1 = new GenderDistributionVo();
        QueryWrapper<UserInfo> wrapper7 = new QueryWrapper<>();
        wrapper7.select("sex")
                .eq("sex",2);
        Integer count7 = this.userInfoMapper.selectCount(wrapper7);
        genderDistributionVo.setTitle("女性用户");
        genderDistributionVo.setAmount(count7);
        list2.add(genderDistributionVo1);
        //地区分布
        List<LocalDistributionVo> list3 = new ArrayList();
        List<String> list1 = new ArrayList();
        Map<String,Integer> map = new HashMap<>();
        String s =
                "上海,河北,山西,内蒙古," +
                        "辽宁,吉林,黑龙江,江苏, 浙江,安徽," +
                        "福建,江西,山东,河南,湖北,湖南,广东, " +
                        "广西,海南,四川,贵州,云南,西藏,陕西,甘肃," +
                        "青海, 宁夏,新疆,北京,天津,重庆,香港,澳门";
        String[] split = s.split(",");
        for (String s1 : split) {
            list1.add(s1);
        }
        for (int i = 0; i < list1.size(); i++) {
            LocalDistributionVo localDistributionVo = new LocalDistributionVo();
            localDistributionVo.setTitle(list1.get(i));
            QueryWrapper<Log> wrapper8 = new QueryWrapper<>();
            wrapper8.select("place")
                .like("place",list1.get(i));
            Integer a = this.logMapper.selectCount(wrapper8);
            map.put(list1.get(i),a);
            localDistributionVo.setAmount(a);
            list3.add(localDistributionVo);
        }
        pageResultbution.setLocalDistribution(list3);

        //地区合计
        List<LocalTotalVo> list4 = new ArrayList();
        String huadong = "江苏省,浙江省,安徽省,福建省,江西省,山东省上海市,台湾省";
        String huanan = "广东省,广西省,海南省,香港和澳门特区";
        String huabei = "河北省,山西省,北京市,天津市,内蒙古自治区";
        String huazhong = "湖北省,湖南省,河南省,武汉";
        String dongbei = "辽宁省,吉林省,黑龙江省";
        String xinan = "四川省,云南省,贵州省,重庆市,西藏自治区,陕西省南部";
        String xibei = "宁夏回族自治区,新疆维吾尔自治区及青海,陕西,甘肃三省之地";
        Integer huadong1 = 0;
        Integer  huanan1= 0;
        Integer  huabei1 = 0;
        Integer  huazhong1 = 0;
        Integer  dongbei1 = 0;
        Integer  xinan1 = 0;
        Integer  xibei1 = 0;
        for (String s1 : list1) {

            if (huadong.contains(s1)){
                 huadong1 += map.get(s1);
            }else if (huanan.contains(s1)){
                huanan1 += map.get(s1);
            }else if (huabei.contains(s1)){
                huabei1 += map.get(s1);
            }else if (huazhong.contains(s1)){
                huazhong1 += map.get(s1);
            }else if (dongbei.contains(s1)){
                dongbei1 += map.get(s1);
            }else if (xinan.contains(s1)){
                xinan1 += map.get(s1);
            }else if (xibei.contains(s1)){
                xibei1 += map.get(s1);
            }
        }
        LocalTotalVo localTotalVo = new LocalTotalVo();
        localTotalVo.setTitle("华东地区");
        localTotalVo.setAmount(huadong1);
        list4.add(localTotalVo);

        LocalTotalVo localTotalVo2 = new LocalTotalVo();
        localTotalVo2.setTitle("华南地区");
        localTotalVo2.setAmount(huanan1);
        list4.add(localTotalVo2);

        LocalTotalVo localTotalVo3 = new LocalTotalVo();
        localTotalVo3.setTitle("华北地区");
        localTotalVo3.setAmount(huabei1);
        list4.add(localTotalVo3);

        LocalTotalVo localTotalVo4 = new LocalTotalVo();
        localTotalVo4.setTitle("华中地区");
        localTotalVo4.setAmount(huazhong1);
        list4.add(localTotalVo4);

        LocalTotalVo localTotalVo5 = new LocalTotalVo();
        localTotalVo5.setTitle("东北地区");
        localTotalVo5.setAmount(dongbei1);
        list4.add(localTotalVo5);

        LocalTotalVo localTotalVo6 = new LocalTotalVo();
        localTotalVo6.setTitle("西南地区");
        localTotalVo6.setAmount(xinan1);
        list4.add(localTotalVo6);

        LocalTotalVo localTotalVo7 = new LocalTotalVo();
        localTotalVo7.setTitle("西北地区");
        localTotalVo7.setAmount(xibei1);
        list4.add(localTotalVo7);

        pageResultbution.setLocalTotal(list4);
        return pageResultbution;
    }

    /**
     * 通过天数获取活跃用户数
     * @param day
     */
    public Integer getActiveByDay(Integer day){
        QueryWrapper<Log> wrapperLog = new QueryWrapper();
        String[] agoByDay = getAgoByDay(day);
        String startDayTime = agoByDay[0];
        String endDayTime = agoByDay[1];
        wrapperLog.select("user_id")
                .gt("log_time",startDayTime)
                .lt("log_time",endDayTime)
                .groupBy("user_id");
        Integer activeCount = this.logMapper.selectCount(wrapperLog);
        return activeCount;
    }


    /**
     *
     * @param day
     * @return
     */
    public String[] getAgoByDay(Integer day){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = new Date();
        String endDayTime = sdf.format(date);
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DAY_OF_YEAR,-day);
        Date addDate = cal.getTime();
        String startDayTime = sdf.format(addDate);
        String[] s =new String[2];
        s[0] = startDayTime;
        s[1] = endDayTime;
        return s;
    }
}
